package com.hqyj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hqyj.excepiton.QuestionException;
import com.hqyj.pojo.Question;
import com.hqyj.dao.QuestionMapper;
import com.hqyj.service.IQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author rock
 * @since 2023-10-07
 */
@Service
@Slf4j
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {

    @Resource
    QuestionMapper questionMapper;
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Override
    public HashMap<String, Object> add(Question question) throws QuestionException {
        HashMap<String, Object> map = null;
        try {
            map = new HashMap<String, Object>();
            int num = questionMapper.insert(question);
            if(num >0 ){
                map.put("code",200);
                map.put("msg","插入成功");
                return map;
            }
            map.put("code",500);
            map.put("msg","插入失败");
        } catch (Exception e) {
            e.printStackTrace();
            throw  new QuestionException(e.getMessage(),500,"插入异常",e.getMessage());
        }
        return map;
    }

    @Override
    public HashMap<String, Object> del(Integer id) throws QuestionException {
        HashMap<String, Object> map = null;
        try {
            map = new HashMap<String, Object>();
            int num = questionMapper.deleteById(id);
            if(num >0 ){
                map.put("code",200);
                map.put("msg","删除成功");
                return map;
            }
            map.put("code",500);
            map.put("msg","删除失败");
        } catch (Exception e) {
            e.printStackTrace();
            throw  new QuestionException(e.getMessage(),500,"删除异常",e.getMessage());
        }
        return map;
    }

    @Override
    public HashMap<String, Object> update(Question question) throws QuestionException {
        HashMap<String, Object> map = null;
        try {
            map = new HashMap<String, Object>();
            int num = questionMapper.updateById(question);
            if(num >0 ){
                map.put("code",200);
                map.put("msg","修改成功");
                return map;
            }
            map.put("code",500);
            map.put("msg","修改失败");
        } catch (Exception e) {
            e.printStackTrace();
            throw  new QuestionException(e.getMessage(),500,"修改异常",e.getMessage());
        }
        return map;
    }

    @Override
    public HashMap<String, Object> queryByPage(Question question) throws QuestionException {
        HashMap<String, Object> map = null;
        try {
            map = new HashMap<String, Object>();
            //1 创建分页对象
            Page<Question> page = new Page<>(question.getPage(),question.getRow());
            //创建查询对象
            QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
            //题目模糊查询
            boolean is = !"".equals(question.getQuName())&&null!=question.getQuName();
            queryWrapper.like(is,"qu_name",question.getQuName());
            //题型精确查询
            boolean iss = !"".equals(question.getQuType())&&null!=question.getQuType();
            queryWrapper.eq(iss,"qu_type",question.getQuType());
            //2 获取查询结果对象
            Page<Question> questionPage = questionMapper.selectPage(page,queryWrapper);
            //当前页集合
            map.put("list",questionPage.getRecords());
            // 总页数
            map.put("totalPage",questionPage.getPages());
            //总条数
            map.put("total",questionPage.getTotal());
            map.put("code",200);
        } catch (Exception e) {
            e.printStackTrace();
            throw  new QuestionException(e.getMessage(),500,"查询异常",e.getMessage());
        }

        return map;
    }

    @Override
    public HashMap<String, Object> queryCacheByPage(Question q) throws QuestionException {
        HashMap<String, Object> map = new HashMap<>();
        //定义一个键名
        String key = "question:page";
        //定义一个总条数的键名
        String keyTotal ="question:total";
        //定义一个总页数的键名
        String keyTotalPage ="question:totalPage";
        //获取总条数
        Object obj = redisTemplate.opsForValue().get(keyTotal);
        Integer total = null;
        if(obj!=null){
            total = Integer.parseInt(obj+"");
        }
        //获取总页数
        Object obj1 = redisTemplate.opsForValue().get(keyTotalPage);
        Integer totalPage = 0;
        if(obj1!=null){
            totalPage = Integer.parseInt(obj1+"");
        }

        //计算起始索引 10   2  5
        int start = q.getPage()==1?0:(q.getPage()>totalPage?(totalPage-1)*q.getRow():(q.getPage()-1)*q.getRow());
        log.info("第{}页，起始索引{}",q.getPage(),start);
        //计算截止索引
        int end = start+q.getRow()-1;
        log.info("第{}页，截止索引{}",q.getPage(),end);

        if(redisTemplate.opsForList().range(key,start,end).size()>0){
            //从缓存取数据
            map.put("list",redisTemplate.opsForList().range(key,start,end));
            // 总页数
            map.put("totalPage",totalPage);
            //总条数
            map.put("total",total);

        }else{
            //1 创建分页对象
            Page<Question> page = new Page<>(q.getPage(),q.getRow());

            //2 获取查询结果对象
            Page<Question> questionPage = questionMapper.selectPage(page,null);
            //当前页集合
            map.put("list",questionPage.getRecords());
            // 总页数
            map.put("totalPage",questionPage.getPages());
            //总条数
            map.put("total",questionPage.getTotal());
            //存入redis缓存中
            if(questionPage.getRecords().size()>0){
                for(Question qu:questionPage.getRecords()){
                    redisTemplate.opsForList().rightPush(key,qu);
                }
            }
            //设置缓存失效时间
            redisTemplate.opsForList().getOperations().expire(key,5, TimeUnit.MINUTES);
            //设置总条数和总页数缓存
            redisTemplate.opsForValue().set(keyTotal,questionPage.getTotal(),5,TimeUnit.MINUTES);
            redisTemplate.opsForValue().set(keyTotalPage,questionPage.getPages(),5,TimeUnit.MINUTES);
        }

        return map;
    }

    @Override
    public void queryQuId()  {
        //判断缓存中是否有数据
        String key ="paper:random";
        Set<Object> set = redisTemplate.opsForSet().members(key);
        if(set.size()==0){
            //查询数据库，获取所有试题id
            List<Integer> list = questionMapper.queryQuId();
            //存入redis的集合中
            for(Integer i:list){
                redisTemplate.opsForSet().add(key,i);
            }
            //设置失效时间
            redisTemplate.opsForSet().getOperations().expire(key,1,TimeUnit.HOURS);

        }



    }
}
